﻿using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SlamDunk.MES.IAppService.DTOs.Outputs.PlanContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation.Maps;
using SlamDunk.MES.Presentation.Models.NotifyModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading.Tasks;

namespace SlamDunk.MES.Client.ViewModels.ProductionPlan
{
    /// <summary>
    /// 生产计划查看视图模型
    /// </summary>
    public class LookViewModel : ScreenBase
    {
        #region # 字段及构造器

        /// <summary>
        /// 计划管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IPlanContract> _planContract;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public LookViewModel(ServiceProxy<IPlanContract> planContract)
        {
            this._planContract = planContract;
        }

        #endregion

        #region # 属性

        #region 生产计划Id —— Guid PlanId
        /// <summary>
        /// 生产计划Id
        /// </summary>
        public Guid PlanId { get; set; }
        #endregion

        #region 生产计划编号 —— string PlanNo
        /// <summary>
        /// 生产计划编号
        /// </summary>
        public string PlanNo { get; set; }
        #endregion

        #region 生产计划名称 —— string PlanName
        /// <summary>
        /// 生产计划名称
        /// </summary>
        public string PlanName { get; set; }
        #endregion

        #region 生产批号 —— string ProductionBatchNo
        /// <summary>
        /// 生产批号
        /// </summary>
        public string ProductionBatchNo { get; set; }
        #endregion

        #region 预期开始时间 —— DateTime? ExpStartTime
        /// <summary>
        /// 预期开始时间
        /// </summary>
        public DateTime? ExpStartTime { get; set; }
        #endregion

        #region 预期结束时间 —— DateTime? ExpEndTime
        /// <summary>
        /// 预期结束时间
        /// </summary>
        public DateTime? ExpEndTime { get; set; }
        #endregion

        #region 最早开始时间 —— DateTime? EarliestStartTime
        /// <summary>
        /// 最早开始时间
        /// </summary>
        public DateTime? EarliestStartTime { get; set; }
        #endregion

        #region 最晚结束时间 —— DateTime? LatestEndTime
        /// <summary>
        /// 最晚结束时间
        /// </summary>
        public DateTime? LatestEndTime { get; set; }
        #endregion

        #region 产品名称 —— string ProductName
        /// <summary>
        /// 产品名称
        /// </summary>
        [DependencyProperty]
        public string ProductName { get; set; }
        #endregion

        #region 物料清单名称 —— string BomName
        /// <summary>
        /// 物料清单名称
        /// </summary>
        [DependencyProperty]
        public string BomName { get; set; }
        #endregion

        #region 预期毛产量 —— decimal? ExpGrossQuantity
        /// <summary>
        /// 预期毛产量
        /// </summary>
        public decimal? ExpGrossQuantity { get; set; }
        #endregion

        #region 预期净产量 —— decimal? ExpNetQuantity
        /// <summary>
        /// 预期净产量
        /// </summary>
        public decimal? ExpNetQuantity { get; set; }
        #endregion

        #region 单位 —— string Unit
        /// <summary>
        /// 单位
        /// </summary>
        public string Unit { get; set; }
        #endregion

        #region 销售订单名称 —— string SaleOrderName
        /// <summary>
        /// 销售订单名称
        /// </summary>
        public string SaleOrderName { get; set; }
        #endregion

        #region 工厂模型名称 —— string FacilityName
        /// <summary>
        /// 工厂模型名称
        /// </summary>
        public string FacilityName { get; set; }
        #endregion

        #region 优先级 —— int? Priority
        /// <summary>
        /// 优先级
        /// </summary>
        /// <remarks>数值越大，优先级越高</remarks>
        public int? Priority { get; set; }
        #endregion

        #region 描述 —— string Description
        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }
        #endregion

        #region 物料需求列表 —— ObservableCollection<PlanMaterialAsk> MaterialAsks
        /// <summary>
        /// 物料需求列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<PlanMaterialAskNm> MaterialAsks { get; set; }
        #endregion

        #endregion

        #region # 方法

        //Initializations

        #region 加载 —— async Task Load(ProductionPlanInfo productionPlan)
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="productionPlan">生产计划</param>
        public async Task Load(ProductionPlanInfo productionPlan)
        {
            this.PlanId = productionPlan.Id;
            this.PlanNo = productionPlan.Number;
            this.PlanName = productionPlan.Name;
            this.ProductionBatchNo = productionPlan.ProductionBatchNo;
            this.ExpStartTime = productionPlan.ExpStartTime;
            this.ExpEndTime = productionPlan.ExpEndTime;
            this.EarliestStartTime = productionPlan.EarliestStartTime;
            this.LatestEndTime = productionPlan.LatestEndTime;
            this.ProductName = productionPlan.ProductInfo.Name;
            this.BomName = productionPlan.BomInfo.Name;
            this.ExpGrossQuantity = productionPlan.ExpGrossQuantity;
            this.ExpNetQuantity = productionPlan.ExpNetQuantity;
            this.Unit = productionPlan.ProductInfo.StandardUnitNo;
            this.SaleOrderName = productionPlan.SaleOrderInfo?.Name;
            this.FacilityName = productionPlan.FacilityInfo?.Name;
            this.Priority = productionPlan.Priority;
            this.Description = productionPlan.Description;

            IEnumerable<ProductionMaterialAskInfo> materialAskInfos = await Task.Run(() => this._planContract.Channel.GetProductionMaterialAsks(this.PlanId));
            IEnumerable<PlanMaterialAskNm> materialAsks = materialAskInfos.Select(x => x.ToNotifyView());
            this.MaterialAsks = new ObservableCollection<PlanMaterialAskNm>(materialAsks);
        }
        #endregion

        #endregion
    }
}
